/*
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.
*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode *head) {
        if (!head || !head->next) return;
        ListNode *slow = head, *fast = head;
        while (fast && fast->next && fast->next->next) {
            fast = fast->next->next;
            slow = slow->next;
        }
        ListNode *l1 = head;
        ListNode *l2 = reverseList(slow->next);
        slow->next = NULL;
        // merge two lists
        while (l1 && l2) {
            ListNode *l1_next = l1->next, *l2_next = l2->next;
            l1->next = l2; l2->next = l1_next;
            l1 = l1_next; l2 = l2_next;
        }
    }
private:
    ListNode *reverseList(ListNode *head) {
        ListNode *prev = NULL;
        while (head) {
            ListNode *next = head->next;
            head->next = prev; prev = head; head = next;
        }
        return prev;
    }
};
